package com.ezcoding.service;

import com.ezcoding.dao.*;
import com.ezcoding.model.*;
import com.ezcoding.utils.PhoneFormatCheckUtil;
import com.ezcoding.utils.StatusUtil;
import com.ezcoding.utils.Tools;

import java.math.BigInteger;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class CompanyService {

    private static CompanyService instance = new CompanyService();

    private final static int CATEGORY_TYPE_PRODUCT = 0;
    private final static int CATEGORY_TYPE_CLIENT = 1;
    private final static int CATEGORY_TYPE_GIVER = 2;
    private final static int CATEGORY_TYPE_FINANCE = 3;

    private final static String NEW_CATEGORY_KEY = "newCategory";

    public static CompanyService getInstance() {
        return instance;
    }

    public boolean checkCompanyExists(String companyId) {
        return CompanyDao.dao.getCompanyByCompanyId(companyId) != null;
    }

    public Map<String, Object> addCompany(String username, String companyName, String contact) {
        if (Tools.checkParaIsInValidate(username, companyName, contact)) {
            return StatusUtil.getFailedStatusWithMessage("参数无效！");
        }

        User user = UserDao.dao.getUserByUsername(username);

        if (user == null) {
            return StatusUtil.getFailedStatusWithMessage("用户不存在！");
        }

        if (!Tools.checkParaIsInValidate(user.getCompanyId())) {
            return StatusUtil.getFailedStatusWithMessage("您已有企业！");
        }

        String usernamePinyin = Tools.toHanyuPinyin(username).split("-")[0];

        String companyId;
        if (PhoneFormatCheckUtil.isPhoneLegal(usernamePinyin)) {
            BigInteger bigInteger = new BigInteger(usernamePinyin, 10);
            companyId = bigInteger.toString(16).toUpperCase();
        } else {
            BigInteger bigInteger = new BigInteger(usernamePinyin, 36);
            companyId = bigInteger.toString(16).toUpperCase();
        }

        Company company = CompanyDao.dao.getCompanyByCompanyId(companyId);

        if (company != null) {
            return StatusUtil.getFailedStatusWithMessage("企业已存在");
        }

        user.setCompanyId(companyId);
        user.setIsBoss(1);

        company = new Company();
        company.setCompanyId(companyId);
        company.setCompanyName(companyName);
        company.setContact(contact);

        return StatusUtil.getStatus(
                company.save() && user.update(),
                "创建成功请重新登录",
                "创建失败");
    }

    public Map<String, Object> updateCompany(
            String username,
            String companyId,
            String taxRate,
            String companyName,
            String contact,
            String tel,
            String fax,
            String website,
            String email,
            String province,
            String city,
            String district,
            String address,
            String account,
            String introduction,
            String ticketCompanyName,
            String taxNum,
            String bank,
            String ticketAccount,
            String ticketTel,
            String ticketAddress) {

        if (Tools.checkParaIsInValidate(username, companyId, companyName, contact)
                || Tools.checkParaIsNullPoint(
                taxRate,
                tel,
                fax,
                website,
                email,
                province,
                city,
                district,
                address,
                account,
                introduction,
                ticketCompanyName,
                taxNum,
                bank,
                ticketAccount,
                ticketTel,
                ticketAddress)) {
            return StatusUtil.getFailedStatusWithMessage("参数无效！");
        }

        Company company = CompanyDao.dao.getCompanyByCompanyId(companyId);

        if (company == null) {
            return StatusUtil.getFailedStatusWithMessage("该企业不存在");
        }

        double oldTaxRate;
        if ("".equals(company.getTaxRate())) {
            oldTaxRate = 0;
        } else {
            oldTaxRate = Double.parseDouble(company.getTaxRate());
        }
        double newTaxRate = Double.parseDouble(taxRate);

        company.setTaxRate(taxRate);
        company.updateInfo(
                companyName,
                contact,
                tel,
                fax,
                website,
                email,
                province,
                city,
                district,
                address,
                account,
                introduction,
                ticketCompanyName,
                taxNum,
                bank,
                ticketAccount,
                ticketTel,
                ticketAddress);

        //更新当前企业已经建立的用户关系
        List<UserRelation> relations = UserRelationDao.dao.getUserRelationsByTargetCompanyId(companyId);

        for (UserRelation relation : relations) {
            relation.setNickName(companyName);
            relation.setNickNamePinyin(Tools.toHanyuPinyin(companyName));
            if (!relation.update()) {
                return StatusUtil.getFailedStatusWithMessage("保存失败时更新用户关系失败！");
            }
        }

        double changeValue = company.getTotalTicket() * (100 / (100 + oldTaxRate) - 100 / (100 + newTaxRate));
        changeValue = Tools.formatDouble(changeValue);

        if (changeValue != 0) {
            User user = UserDao.dao.getUserByUsername(username);
            Message message = new Message(
                    username,
                    "",
                    1,
                    changeValue,
                    0,
                    0,
                    0,
                    Message.MESSAGE_TYPE_TAXRATECHANGE,
                    user == null ? "" : user.getNickName(),
                    String.format("税率变更%.2f%%->%.2f%%", oldTaxRate, newTaxRate));

            if (!message.save()) {
                return StatusUtil.getFailedStatusWithMessage("税率变更记录建立失败！");
            }
        }

        return StatusUtil.getStatus(company.update(), "更新成功[资产变化" + changeValue + "]", "更新失败");
    }

    public Map<String, Object> queryCompany(String username, String companyId, String successMessage) {
        if (Tools.checkParaIsInValidate(username, companyId)) {
            return StatusUtil.getFailedStatusWithMessage("参数无效！");
        }

        Company company = CompanyDao.dao.getCompanyByCompanyId(companyId);

        if (company == null) {
            return StatusUtil.getFailedStatusWithMessage("企业不存在！");
        }

        //合计库存总额
        List<Product> products = ProductDao.dao.getProductsByCompanyId(companyId);
        double totalStore = 0;//库存总额
        for (Product product : products) {
            totalStore += (product.getCount() + product.getSanbao()) * product.getInPrice();
        }

        List<UserRelation> relations = UserRelationDao.dao.getUserRelationsBySourceUsername(username);

        company.updateInfo(relations);

        if (!company.update()) {
            return StatusUtil.getFailedStatusWithMessage("企业信息更新失败！");
        }

        Map<String, Object> res = new HashMap<>();
        Map<String, Object> data = new HashMap<>();

        data.put("company", company);
        data.put("totalStore", totalStore);
        res.put("data", data);

        return StatusUtil.getSuccessStatusWithMessage(res, successMessage);
    }

    public Map<String, Object> joinCompany(String username, String companyId) {
        if (Tools.checkParaIsInValidate(username, companyId)) {
            return StatusUtil.getFailedStatusWithMessage("参数无效！");
        }

        User user = UserDao.dao.getUserByUsername(username);
        Company company = CompanyDao.dao.getCompanyByCompanyId(companyId);

        if (user == null) {
            return StatusUtil.getFailedStatusWithMessage("用户名不存在！");
        }

        if (!user.getCompanyId().isEmpty()) {
            return StatusUtil.getFailedStatusWithMessage("您已有企业！");
        }

        if (company == null) {
            return StatusUtil.getFailedStatusWithMessage("要加入的企业不存在！");
        }

        user.setCompanyId(companyId);

        Map<String, Object> res = new HashMap<>();
        Map<String, Object> data = new HashMap<>();
        data.put("company", company);
        res.put("data", data);

        return StatusUtil.getStatus(res, user.update(), "加入企业成功！", "加入企业失败！");
    }

    public Map<String, Object> updateCategory(String categoryTypeStr, String companyId, String category) {
        if (Tools.checkParaIsInValidate(categoryTypeStr, companyId, category)) {
            return StatusUtil.getFailedStatusWithMessage("参数无效！");
        }

        int categoryType = Tools.parseNatureInteger(categoryTypeStr);
        if (categoryType < 0 || categoryType > 3) {
            return StatusUtil.getFailedStatusWithMessage("类别类型参数错误！");
        }

        Company company = CompanyDao.dao.getCompanyByCompanyId(companyId);

        if (company == null) {
            return StatusUtil.getFailedStatusWithMessage("企业不存在！");
        }

        switch (categoryType) {
            case CATEGORY_TYPE_PRODUCT:
                company.setProductCategory(category);
                break;
            case CATEGORY_TYPE_CLIENT:
                company.setClientCategory(category);
                break;
            case CATEGORY_TYPE_GIVER:
                company.setGiverCategory(category);
                break;
            case CATEGORY_TYPE_FINANCE:
                company.setFinanceCategory(category);
                break;
            default:
                break;
        }

        return StatusUtil.getStatus(company.update(), "类别更新成功！", "类别更新失败！");
    }

    public Map<String, Object> updateItemCategory(
            String categoryTypeStr,
            String username,
            String companyId,
            String oldPrimaryDirectory,
            String oldSecondaryDirectory,
            String newPrimaryDirectory,
            String newSecondaryDirectory) {

        if (Tools.checkParaIsInValidate(categoryTypeStr, username, companyId, oldPrimaryDirectory)) {
            return StatusUtil.getFailedStatusWithMessage("参数无效！");
        }

        if (Tools.checkParaIsNullPoint(oldSecondaryDirectory, newPrimaryDirectory, newSecondaryDirectory)) {
            return StatusUtil.getFailedStatusWithMessage("参数无效！");
        }

        User user = UserDao.dao.getUserByUsername(username);

        if (user == null || !user.getCompanyId().equals(companyId)) {
            return StatusUtil.getFailedStatusWithMessage("用户不存在或企业ID错误！");
        }

        int categoryType = Tools.parseNatureInteger(categoryTypeStr);
        if (categoryType < 0 || categoryType > 3) {
            return StatusUtil.getFailedStatusWithMessage("类别类型参数错误！");
        }

        Map<String, Object> res = new HashMap<>();
        Map<String, Object> data = new HashMap<>();
        res.put("data", data);
        boolean updateRes = false;
        switch (categoryType) {
            case CATEGORY_TYPE_PRODUCT:
                if (oldSecondaryDirectory.isEmpty()) {
                    updateRes = ProductDao.dao.updateProductsPrimaryDirectory(
                            companyId,
                            oldPrimaryDirectory,
                            newPrimaryDirectory);
                    data.put(NEW_CATEGORY_KEY, newPrimaryDirectory);
                } else {
                    updateRes = ProductDao.dao.updateProductsDirectory(
                            companyId,
                            oldPrimaryDirectory,
                            oldSecondaryDirectory,
                            newSecondaryDirectory);
                    data.put(NEW_CATEGORY_KEY, newSecondaryDirectory);
                }
                break;
            case CATEGORY_TYPE_CLIENT:
                if (oldSecondaryDirectory.isEmpty()) {
                    updateRes = UserRelationDao.dao.updateUserRelationsPrimaryDirectory(
                            username,
                            oldPrimaryDirectory,
                            newPrimaryDirectory,
                            UserRelation.RELATION_TYPE_CLIENT);
                    data.put(NEW_CATEGORY_KEY, newPrimaryDirectory);
                } else {
                    updateRes = UserRelationDao.dao.updateUserRelationsDirectory(
                            username,
                            oldPrimaryDirectory,
                            oldSecondaryDirectory,
                            newSecondaryDirectory,
                            UserRelation.RELATION_TYPE_CLIENT);
                    data.put(NEW_CATEGORY_KEY, newSecondaryDirectory);
                }
                break;
            case CATEGORY_TYPE_GIVER:
                if (oldSecondaryDirectory.isEmpty()) {
                    updateRes = UserRelationDao.dao.updateUserRelationsPrimaryDirectory(
                            username,
                            oldPrimaryDirectory,
                            newPrimaryDirectory,
                            UserRelation.RELATION_TYPE_GIVER);
                    data.put(NEW_CATEGORY_KEY, newPrimaryDirectory);
                } else {
                    updateRes = UserRelationDao.dao.updateUserRelationsDirectory(
                            username,
                            oldPrimaryDirectory,
                            oldSecondaryDirectory,
                            newSecondaryDirectory,
                            UserRelation.RELATION_TYPE_GIVER);
                    data.put(NEW_CATEGORY_KEY, newSecondaryDirectory);
                }
                break;
            case CATEGORY_TYPE_FINANCE:
                int financeType = oldPrimaryDirectory.equals("收入") ? 0 : 1;
                updateRes = FinanceDao.dao.updateFinanceDirectory(
                        companyId,
                        financeType,
                        oldSecondaryDirectory,
                        newSecondaryDirectory);
                data.put(NEW_CATEGORY_KEY, newSecondaryDirectory);
                break;
            default:
                break;
        }

        return StatusUtil.getStatus(res, updateRes, "更新成功！", "更新失败");
    }

    public Map<String, Object> deleteItemCategory(
            String categoryTypeStr,
            String username,
            String companyId,
            String primaryDirectory,
            String secondaryDirectory) {
        if (Tools.checkParaIsInValidate(categoryTypeStr, username, companyId, primaryDirectory)) {
            return StatusUtil.getFailedStatusWithMessage("参数无效！");
        }

        if (Tools.checkParaIsNullPoint(secondaryDirectory)) {
            return StatusUtil.getFailedStatusWithMessage("参数无效！");
        }

        int categoryType = Tools.parseNatureInteger(categoryTypeStr);
        if (categoryType < 0 || categoryType > 3) {
            return StatusUtil.getFailedStatusWithMessage("类别类型参数错误！");
        }

        User user = UserDao.dao.getUserByUsername(username);
        if (user == null || !user.getCompanyId().equals(companyId)) {
            return StatusUtil.getFailedStatusWithMessage("用户不存在或企业ID错误！");
        }

        long count = 0;
        switch (categoryType) {
            case CATEGORY_TYPE_PRODUCT:
                if (secondaryDirectory.isEmpty()) {
                    count = ProductDao.dao.getProductsCountByCompanyIdAndPrimaryDirectory(companyId, primaryDirectory);
                } else {
                    count = ProductDao.dao.getProductsCountByCompanyIdAndDirectory(companyId, primaryDirectory, secondaryDirectory);
                }
                break;
            case CATEGORY_TYPE_CLIENT:
                if (secondaryDirectory.isEmpty()) {
                    count = UserRelationDao.dao.getUserRelationsCountByUsernameAndPrimaryDirectory(
                            username,
                            primaryDirectory,
                            UserRelation.RELATION_TYPE_CLIENT);
                } else {
                    count = UserRelationDao.dao.getUserRelationsCountByUsernameAndDirectory(
                            username,
                            primaryDirectory,
                            secondaryDirectory,
                            UserRelation.RELATION_TYPE_CLIENT);
                }
                break;
            case CATEGORY_TYPE_GIVER:
                if (secondaryDirectory.isEmpty()) {
                    count = UserRelationDao.dao.getUserRelationsCountByUsernameAndPrimaryDirectory(
                            username,
                            primaryDirectory,
                            UserRelation.RELATION_TYPE_GIVER);
                } else {
                    count = UserRelationDao.dao.getUserRelationsCountByUsernameAndDirectory(
                            username,
                            primaryDirectory,
                            secondaryDirectory,
                            UserRelation.RELATION_TYPE_GIVER);
                }
                break;
            case CATEGORY_TYPE_FINANCE:
                int financeType = primaryDirectory.equals("收入") ? 0 : 1;
                count = FinanceDao.dao.getFinanceItemsCount(companyId, financeType, secondaryDirectory);
                break;
            default:
                break;
        }

        return StatusUtil.getStatus(count == 0, "删除成功！", "当前类目不为空，无法删除！");
    }

    public Map<String, Object> homeCount(
            int type,
            String username,
            String companyId,
            String oldValueStr,
            String countValueStr) {
        if (Tools.checkParaIsInValidate(username, companyId, oldValueStr, countValueStr)) {
            return StatusUtil.getFailedStatusWithInvalidParaMessage();
        }

        double oldValue = Double.parseDouble(oldValueStr);
        double countValue = Double.parseDouble(countValueStr);

        Company company = CompanyDao.dao.getCompanyByCompanyId(companyId);
        User user = UserDao.dao.getUserByUsername(username);

        if (company == null) {
            return StatusUtil.getFailedStatusWithMessage("企业不存在！");
        }

        if (user == null) {
            return StatusUtil.getFailedStatusWithMessage("用户不存在！");
        }

        double curValue = type == 0 ? company.getTotalTicket() : company.getTotalMoney();

        if (curValue != oldValue) {
            return StatusUtil.getFailedStatusWithMessage("本地数据与服务器数据不符请刷新数据！");
        }

        if (type == 0) {
            company.setTotalTicket(curValue + countValue);
        } else {
            company.setTotalMoney(curValue + countValue);
        }

        if (!company.update()) {
            return StatusUtil.getFailedStatusWithMessage("盘点数据更新失败！");
        }

        Message message = new Message(
                username,
                "",
                1,
                countValue,
                0,
                0,
                0,
                Message.MESSAGE_TYPE_TICKETCOUNT + type,
                user.getNickName(),
                type == 0 ? "发票盘点" : "资金盘点");

        if (!message.save()) {
            return StatusUtil.getFailedStatusWithMessage("盘点记录建立失败！");
        }

        return StatusUtil.getSuccessStatusWithMessage("盘点成功");
    }
}
